#include<iostream>
#include <cstring>
using namespace std;
const int N=1e3+10;
struct node
{
    int vi;//体积
    int wi;//价值
}nums[N];
int Value[N];
int main()
{
    int n,v;cin>>n>>v;
    for(int i=1;i<=n;i++)
    {
        cin>>nums[i].vi>>nums[i].wi;
    }

    //在n个物品中选出背包所能装取的最大价值
    for(int i=1;i<=n;i++)
    {
        //这里是倒序的原因是因为这里的当前物品需要上一件物品做出抉择时的最大价值
        //如果不是倒叙，可能对物品进行重复选取
        for(int j=v;j>=nums[i].vi;j--)
        {
            Value[j]=max(Value[j],Value[j-nums[i].vi]+nums[i].wi);
        }
    }
    cout<<Value[v]<<endl;


    memset(Value,-1,sizeof(Value));
    Value[0]=0;
    //背包装满所能装取的最大价值
    for(int i=1;i<=n;i++)
    {
        for(int j=v;j>=nums[i].vi;j--)
        {
            if(Value[j-nums[i].vi]!=-1)
            Value[j]=max(Value[j],Value[j-nums[i].vi]+nums[i].wi);
        }
    }
    cout<<(Value[v]==-1?0:Value[v])<<endl;
}